package com.ycy.dynamic;

import com.ycy.dynamic.f.*;
import com.ycy.util.JsonUtil;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.BpmnAutoLayout;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.*;
import org.flowable.common.engine.api.FlowableException;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.impl.cmd.AbstractDynamicInjectionCmd;
import org.flowable.engine.impl.context.Context;
import org.flowable.engine.impl.dynamic.BaseDynamicSubProcessInjectUtil;
import org.flowable.engine.impl.dynamic.DynamicUserTaskBuilder;
import org.flowable.engine.impl.persistence.entity.DeploymentEntity;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager;
import org.flowable.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
import org.flowable.task.api.Task;
import org.flowable.task.service.TaskService;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.beans.BeanUtils;

import java.util.*;

public class BeforeDynamicTaskCmd extends AbstractDynamicInjectionCmd implements Command<Void> {

  //流程实例id
  protected String processInstanceId;

  //后加签的节点信息
  private DynamicUserTaskBuilder signUserTaskBuilder;

  //当前流程节点任务实例id
  private String taskInstanceId;

  //当前流程节点定义id
  private String taskDefinitionKey;

  private String newUserTaskId = null;

  private String deploymentid = null;

  private String  processDefinitionId = null;

  //TODO taskInstanceId 多签或签 人员
  public BeforeDynamicTaskCmd(DynamicUserTaskBuilder signUserTaskBuilder, String taskInstanceId, String processInstanceId) {
    newUserTaskId = "rdfaaddnewusertask" + System.currentTimeMillis();
    this.signUserTaskBuilder = signUserTaskBuilder;
    this.taskInstanceId = taskInstanceId;
    this.processInstanceId = processInstanceId;
  }

  @Override
  public Void execute(CommandContext commandContext) {
    createDerivedProcessDefinitionForProcessInstance(commandContext, processInstanceId);
    return null;
  }

  @Override
  protected void updateBpmnProcess(CommandContext commandContext, Process process,
                                   BpmnModel bpmnModel, ProcessDefinitionEntity originalProcessDefinitionEntity, DeploymentEntity newDeploymentEntity) {
    //找到当前节点的实体
    TaskService taskService = CommandContextUtil.getTaskService(commandContext);
    TaskEntity taskEntity = taskService.getTask(taskInstanceId);
    if (taskEntity == null) {
      throw new FlowableObjectNotFoundException("task:" + taskInstanceId + " not found");
    }

    ExecutionEntity currentExecutionEntity = CommandContextUtil.getExecutionEntityManager(commandContext).findById(taskEntity.getExecutionId());
    if (currentExecutionEntity == null) {
      throw new FlowableObjectNotFoundException("task:" + taskInstanceId + ",execution:" + taskEntity.getExecutionId() + " not found");
    }
    //获取当前执行节点
    String activityId = currentExecutionEntity.getActivityId();
    FlowElement currentFlowElemet = process.getFlowElement(activityId, true);
    if (!(currentFlowElemet instanceof UserTask)) {
      throw new FlowableException("usertask type error");
    }
    taskDefinitionKey = activityId;

    //定义新的审批节点
    UserTask addNewUserTask = new UserTask();
    addNewUserTask.setId(newUserTaskId);
    addNewUserTask.setName("动态新增人员审批节点");
    MultiInstanceLoopCharacteristics loopCharacteristics = new MultiInstanceLoopCharacteristics();
    loopCharacteristics.setSequential(false);
    loopCharacteristics.setInputDataItem("ASSIGNEE_" + addNewUserTask.getId() + "_LIST");
    loopCharacteristics.setElementVariable("ASSIGNEE_" + addNewUserTask.getId() + "_ID");
    //支持多签或签 TODO
    loopCharacteristics.setCompletionCondition(CompletionConditionEnum.byType(1).getCompletionCondition());
    RdfaBpExpressionAccountIds expressionAccountIds = new RdfaBpExpressionAccountIds();
    //指定审批人 TODO
    RdfaBpExpressionInfo expressionInfo = new RdfaBpExpressionInfo();
    expressionInfo.setType(BpConstants.EXPRESSION_TYPE_SPECIFIED_ACCOUNT_IDS);
    Set<Long> validAssigneeValueSet = new HashSet<>();
    validAssigneeValueSet.add(1L);
    expressionAccountIds.setAccountIds(validAssigneeValueSet);
    expressionInfo.setValue(JsonUtil.objToString(expressionAccountIds));
    RdfaBpDocumentation bpDocumentation = new RdfaBpDocumentation();
    bpDocumentation.setExpressionInfo(expressionInfo);
    addNewUserTask.setDocumentation(JsonUtil.objToString(bpDocumentation));
    addNewUserTask.setLoopCharacteristics(loopCharacteristics);
    addNewUserTask.setAssignee("${" + loopCharacteristics.getElementVariable() + "}");

    List<SequenceFlow> incomingFlows = new ArrayList<>();
    List<SequenceFlow> oldIncomingFlows = ((UserTask) currentFlowElemet).getIncomingFlows();
    for (int i = 0; i < oldIncomingFlows.size(); i++) {
      SequenceFlow ixSequenceFlow = oldIncomingFlows.get(i);
      SequenceFlow newIncomingSequenceFlow = new SequenceFlow();
      BeanUtils.copyProperties(ixSequenceFlow, newIncomingSequenceFlow);
      newIncomingSequenceFlow.setSourceRef(ixSequenceFlow.getSourceRef());
      newIncomingSequenceFlow.setTargetRef(addNewUserTask.getId());
      newIncomingSequenceFlow.setId(ixSequenceFlow.getSourceRef() + "-" + addNewUserTask.getId());
      incomingFlows.add(newIncomingSequenceFlow);
      //删除原先节点的出线
      process.removeFlowElement(ixSequenceFlow.getId());
      //添加新线
      process.addFlowElement(newIncomingSequenceFlow);
    }

    List<SequenceFlow> outgoingFlows = new ArrayList<>();
    SequenceFlow newOutgoingFlow = new SequenceFlow(addNewUserTask.getId(), currentFlowElemet.getId());
    newOutgoingFlow.setName("边");
    newOutgoingFlow.setId(addNewUserTask.getId() + "-" + currentFlowElemet.getId());
    outgoingFlows.add(newOutgoingFlow);
    process.addFlowElement(newOutgoingFlow);
    addNewUserTask.setIncomingFlows(incomingFlows);
    addNewUserTask.setOutgoingFlows(outgoingFlows);
    process.addFlowElement(addNewUserTask);

    //重新生成图 GraphicInfo
    new BpmnAutoLayout(bpmnModel).execute();

    Process process1 = bpmnModel.getProcesses().get(0);
    Collection<FlowElement> flowElements = process1.getFlowElements();
    for (FlowElement flowElement : flowElements) {
      System.out.println(flowElement);
    }

    //当前流程的重新定义
    BaseDynamicSubProcessInjectUtil.processFlowElements(commandContext, process, bpmnModel, originalProcessDefinitionEntity, newDeploymentEntity);
    System.out.println("1");
  }

  @Override
  protected void updateExecutions(CommandContext commandContext, ProcessDefinitionEntity processDefinitionEntity,
                                  ExecutionEntity processInstance, List<ExecutionEntity> childExecutions) {

    this.deploymentid = processDefinitionEntity.getDeploymentId();
    String id = processDefinitionEntity.getId();
//    Set<String> parentExecutionEntityIds = new HashSet<>();
//
//    ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext);
//    BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(processDefinitionEntity.getId());
//    TaskService taskService = CommandContextUtil.getTaskService(commandContext);
//    List<TaskEntity> taskEntities = taskService.findTasksByProcessInstanceId(processInstanceId);
//    // 删除当前活动任务
//    for (TaskEntity taskEntity : taskEntities) {
//      if (StringUtils.equals(taskEntity.getTaskDefinitionKey(), taskDefinitionKey)) {
//        ExecutionEntity executionEntity = executionEntityManager.findById(taskEntity.getExecutionId());
//        parentExecutionEntityIds.add( executionEntity.getParentId());
//        // 删除 ACT_RU_EXECUTION
//        CommandContextUtil.getExecutionEntityManager().deleteExecutionAndRelatedData(executionEntity, "superOp");
//        // 更新 ACT_HI_TASKINST
//        CommandContextUtil.getHistoryManager().recordTaskEnd(taskEntity, executionEntity, "superOp");
//
//        CommandContextUtil.getIdentityLinkService().deleteIdentityLinksByTaskId(taskEntity.getId());
//        // 删除 ACT_RU_TASK
//        taskService.deleteTask(taskEntity, true);
//      }
//    }
//    for (String parentExecutionEntityId : parentExecutionEntityIds) {
//      ExecutionEntity executionEntity = executionEntityManager.findById(parentExecutionEntityId);
//      // 删除 ACT_RU_EXECUTION
//      CommandContextUtil.getExecutionEntityManager().deleteExecutionAndRelatedData(executionEntity, "superOp");
//    }
//
//    ExecutionEntity execution = executionEntityManager.createChildExecution(processInstance);
//    //TODO 加塞一个变量
//    List<Object> value = new ArrayList<>();
//    value.add("ycy");
//    value.add("ycy2");
//    execution.setVariable("ASSIGNEE_" + newUserTaskId + "_LIST", value);
//
//
//    //设置活动后的节点
//    UserTask userTask = (UserTask) bpmnModel.getProcessById(processDefinitionEntity.getKey()).getFlowElement(newUserTaskId);
//
//    execution.setCurrentFlowElement(userTask);
//    Context.getAgenda().planContinueProcessOperation(execution);

  }

  public String getDeploymentid() {
    return deploymentid;
  }

  public void setDeploymentid(String deploymentid) {
    this.deploymentid = deploymentid;
  }
}
